﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SPC
{
    /// <summary>
    /// 不良率P控制图
    /// </summary>
    class SpcP : ISPC
    {   
        double[] pi;//组内不良率
        double[] ni;//每组检查数量
        double pbar;
        double pSigama;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="samples">每组检查数量</param>
        /// <param name="NGs">每组不良数量</param>
        public SpcP(double[] samples, double[] NGs)
        {            
            this.ni = samples;
            pi = new double[ni.Length];
            for (int i = 0; i < pi.Length; i++)
            {
                pi[i] = NGs[i] / ni[i];
            }
            pbar = pi.Average();
            pSigama = Math.Sqrt(pbar * (1 - pbar) / ni.Sum());
            
        }
        public double LSL
        { set { } }
        public double USL
        { set { } }
        public double CP()
        {            
            return pbar;
        }

        public double CPK()
        {            
            return pbar;
        }

        public SCtrlDiagram[] GetCtrlDiagrams()
        {
            SCtrlDiagram[] diags = new SCtrlDiagram[1];
            double nbar = ni.Average();
            diags[0] = new SCtrlDiagram()
            {
                diagramName = DiagramName.p,
                points = pi,

                cl = pbar
            };
            if (ni.Min()==ni.Max())//样本数相等时
            {   
                double lcl= pbar - 3 * pSigama;
                diags[0].lcl = lcl > 0 ? lcl : 0;
                diags[0].ucl = pbar + 3 * pSigama;
            }
            else if(ni.Min()>nbar*0.25&&ni.Max()<nbar*0.25)
            {
                double sigmab = Math.Sqrt(pbar * (1 - pbar) / nbar);
                double lcl= pbar - 3 * sigmab;
                diags[0].lcl = lcl > 0 ? lcl : 0;
                diags[0].ucl = pbar + 3 * sigmab;
            }
            else
            {
                diags[0].lcls = new double[ni.Length];
                diags[0].ucls = new double[ni.Length];
                for (int i = 0; i < ni.Length; i++)
                {
                    double sigmab = Math.Sqrt(pbar * (1 - pbar) / ni[i]);
                    double lcl = pbar - 3 * sigmab;
                    diags[0].lcls[i] = lcl > 0 ? lcl : 0;
                    diags[0].ucls[i] = pbar + 3 * sigmab;
                }
            }            
            
            return diags;
        }

        public double PP()
        {
            return pbar;
        }

        public double PPK()
        {
            return pbar;
        }
    }
}
